package cn.lycode.system.service.impl;

import cn.lycode.common.core.domain.model.SelectIdsDTO;
import cn.lycode.common.core.page.PageResult;
import cn.lycode.common.core.page.PageUtil;
import cn.lycode.common.enums.ErrorEnum;
import cn.lycode.system.domain.dto.sysdict.SysDictAddDTO;
import cn.lycode.system.domain.dto.sysdict.SysDictListDTO;
import cn.lycode.system.domain.dto.sysdict.SysDictUpDTO;
import cn.lycode.system.domain.entity.SysDict;
import cn.lycode.system.domain.entity.SysDictType;
import cn.lycode.system.domain.vo.DictCustomVO;
import cn.lycode.system.mapper.SysDictMapper;
import cn.lycode.system.mapper.SysDictTypeMapper;
import cn.lycode.system.service.SysDictService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Title: SysDictServiceImpl
 * @Author lyg
 * @Date 2024/7/16 15:48
 * @description:
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class SysDictServiceImpl implements SysDictService {

    private final SysDictMapper sysDictMapper;
    private final SysDictTypeMapper sysDictTypeMapper;

    private static Long generateCustomId(Long firstPart, Long secondPart) {
        if (secondPart == null) {
            secondPart = 1L;
        }else {
            secondPart += 1;
        }
        String paddedFirstPart = String.format("%04d", firstPart); // 格式化为四位数字，不足补零
        String paddedSecondPart = String.format("%04d", secondPart % 10000); // 格式化为四位数字，不足补零
        String part = paddedFirstPart + paddedSecondPart;
        return Long.valueOf(part);
    }

    @Override
    public PageResult<SysDict> list(SysDictListDTO dto) {
        PageUtil.startPage(dto);
        List<SysDict> sysDictList = sysDictMapper.list(dto);
        return PageUtil.getPageResult(sysDictList);
    }

    /**
     * 字典添加不支持并发
     * @param dto
     * @return
     */
    @Override
    public int add(SysDictAddDTO dto) {
        SysDict sysDict = dto.buildAddEntity();
        //检查SysDictType是否存在
        int dictTypeCount = sysDictTypeMapper.countDictTypeById(dto.getSysDictTypeId());
        ErrorEnum.INVALID_ID.assertTrue(dictTypeCount > 0);

        // 检查是否已存在相同的SysDict
        int codeNameCount = sysDictMapper.countDictCodeNameByDictTypeId(sysDict);
        ErrorEnum.EXIST_DICT.assertTrue(codeNameCount < 1);

        // 查出最大ID
        Long maxDictId = sysDictMapper.selectMaxDictId(dto.getSysDictTypeId());
        long newDictId = generateCustomId(dto.getSysDictTypeId(), maxDictId);

        sysDict.setId(newDictId);

        // 获取详细信息
        SysDictType sysDictType = sysDictTypeMapper.selectSysDictTypeById(dto.getSysDictTypeId());
        String typeCode = sysDictType.getTypeCode();
        // TODO 清除Redis缓存
//        redisCache.clearDict(typeCode);
        return sysDictMapper.insertSysDict(sysDict);
    }

    @Override
    public int update(SysDictUpDTO dto) {
        SysDict sysDict = dto.buildUpdateEntity();
        // 检查是否已存在相同的SysDict
        int codeNameCount = sysDictMapper.countDictCodeNameByDictTypeId(sysDict);
        ErrorEnum.EXIST_DICT.assertTrue(codeNameCount < 1);
        int ret = sysDictMapper.updateSysDict(sysDict);

        // 获取详细信息
        SysDictType sysDictType = sysDictTypeMapper.selectSysDictTypeById(dto.getSysDictTypeId());
        String typeCode = sysDictType.getTypeCode();
        // TODO 清除Redis缓存
//        redisCache.clearDict(typeCode);
        return ret;
    }

    @Override
    public int lock(SelectIdsDTO dto) {
        return sysDictMapper.lockSysDictById(dto.getIds());
    }

    @Override
    public int delete(SelectIdsDTO dto) {
        return sysDictMapper.deleteByIdList(dto.getIds());
    }



    //获取所有的字典数据，
    @Override
    public Map<String, List<DictCustomVO>> dictAll() {
        List<DictCustomVO> dictCustomVOS = sysDictMapper.listDict("");
        Map<String, List<DictCustomVO>> dictMap = dictCustomVOS.stream()
                .collect(Collectors.groupingBy(DictCustomVO::getSysDictTypeCode,
                        LinkedHashMap::new, // 使用 LinkedHashMap 作为分组的容器，有序解决乱序问题
                        Collectors.mapping(dictVO -> {
                            DictCustomVO target = new DictCustomVO();
                            BeanUtils.copyProperties(dictVO, target);
                            return target;
                        }, Collectors.toList())));
        //TODO 字典数据存入缓存 ,动态路由刷新每次都需要获取所有字典数据，存入缓存增加效率
//        redisCache.putAllDict(dictMap);
        log.debug("查询所有字典！");
        return dictMap;
    }
}
